package client_tests;

import net.es.lookup.common.exception.LSClientException;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * User: Luke Lamonica
 * Date: 9/20/13
 * TestManager is the main entry point for the client test program. It gathers
 * test specs from the program's arguments, initializes the appropriate test,
 * executes it, and reports the results.
 * Note: all error and exception messages must be printed to stderr so that
 * the framework thread that manages the execution of this program will be
 * able to interpret it correctly. The framework thread will include any data
 * printed to stdout in the test output file.
 */
public class TestManager {

//    private static Logger LOG = Logger.getLogger(TestManager.class);
    private static String logConfig = "/home/luke/log4j.properties";
    private static Set<String> tests = new HashSet<String>(Arrays.asList("serial-query", "serial-renew", "serial-delete", "parallel-regs", "parallel-queries"));
    private static final int ARG_COUNT = 7;

    public static void main(String[] args) {

        System.setProperty("log4j.configuration", "file:" + logConfig);
        String sourceHost = null;
        String targetHost = null;
        int port = -1;
        String test = null;
        int op_interval = Integer.MAX_VALUE;
        int numThreads = -1;
        int testRounds = -1;

        /* Check that the arguments are valid */
        try {

            if (args.length != ARG_COUNT) {

                throw new IllegalArgumentException();
            }
            sourceHost = args[0];
            targetHost = args[1];
            port = Integer.decode(args[2]);
            test = args[3];
            op_interval = Integer.decode(args[4]);
            numThreads = Integer.decode(args[5]);
            testRounds = Integer.decode(args[6]);

            if (port < 1 || numThreads < 0 || testRounds < 0) {

                throw new IllegalArgumentException();
            }

            if (!tests.contains(test)) {

                throw new Exception();
            }
        } catch (IllegalArgumentException e) {

            System.err.println("Usage: java -jar <jar-name> <source host> <target host> <port> <test> <operation_interval> <num_threads> <num_test_rounds>");
            if (port < 1 && args.length == ARG_COUNT) {

                System.err.println("<port> must be a positive integer");
            }
            if ((numThreads < 0 || testRounds < 0) && args.length == ARG_COUNT) {

                System.err.println("<numThreads> and <testRounds> must be integers >= 0");
            }
            if (op_interval == Integer.MAX_VALUE
                || numThreads == Integer.MAX_VALUE
                || testRounds == Integer.MAX_VALUE) {

                System.err.println("<operation_interval>, <num_threads>, and <num_test_rounds> must be integers");
            }
            System.exit(1);
        } catch (Exception e) {

            System.err.println("Usage: java -jar <jar-name> <source host> <target host> <port> <test> <operation_interval> <num_threads> <num_test_rounds>");
            System.err.println("\"" + args[3] + "\" is not a valid test name. Select from the following:");
            System.err.println(tests);
            System.exit(1);
        }

        /* Determine the appropriate test to run */
        ScalabilityTest st = null;
        if (test.equals("serial-query")) {

            st = new SerialQuery();
        } else if (test.equals("serial-renew")) {

            st = new SerialRenew();
        } else if (test.equals("serial-delete")) {

            st = new SerialDelete();
        } else if (test.equals("parallel-regs")) {

            st = new MultipleRegistrations();
        } else if (test.equals("parallel-queries")) {

            st = new SimultaneousQueries();
        }

        try {

            /* Initialize the test instance with the appropriate specs */
            st.initialize(targetHost, port, sourceHost, op_interval,
                          numThreads, testRounds);

            /* Begin the test */
            st.runTest();

            /* Trigger the printing of the results to stdout */
            st.printResults();
        } catch (LSClientException e) {

            System.err.println("LSClientException occurred on " + sourceHost);
            e.printStackTrace();
            System.exit(1);
        }
    }
}
